/**
 *
 */
package com.engine.Mangers;

import java.util.Date;
import java.util.List;

import org.hibernate.Session;

import com.util.EngineUtil;
import com.wfe.db.SessionUtil;
import com.wfe.db.WorkFlowEngineQueryUtil;
import com.wfe.mapping.client.WfPlanTask;
import com.wfe.mapping.client.WfProject;
import com.wfe.mapping.client.WfProjectStatus;
import com.wfe.mapping.client.WfProjectTask;
import com.wfe.mapping.client.WfProjectTaskStatus;
import com.wfe.mapping.client.WfTaskRouting;
import com.wfe.mapping.client.WfTaskType;

/**
 * @author kareem_yehya
 * @since 25 April 2009 * @version 1.0.0.1
 */
public class JoinManger implements Runnable
{

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run()
	{

		while(true)
		{
			try
			{
				System.out.println("Enter Join Manger main Thread");
				List<WfProjectTask> taskList = loadAssignedJoinTasks(10);

				if(taskList.size() > 0)
				{
					for(WfProjectTask projectTask : taskList)
					{
						if(isAllBranchesExecuted(projectTask))
						{
							updateTask(projectTask);
							Router.route(projectTask);
						}

					}
				}
				else
				{

					System.out.println("No Any Joins To Execute");
				}

				Thread.sleep(6000);
			}catch(Exception e)
			{
				e.printStackTrace();
			}

		}
	}

	private static List<WfProjectTask> getWfProjectTasks(WfProject project)
	{

		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			List<WfProjectTask> retList = WorkFlowEngineQueryUtil.getWfProjectTasksByProject(project, session);
			// ???? retList = CloneUtil.cloneWfProjectTaskList(retList);

			return retList;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	private boolean isAllBranchesExecuted(WfProjectTask projectTask)
	{
		WfProject mainProject = projectTask.getWfProject();
		java.util.List<WfProjectTask> allProjectTasks = getWfProjectTasks(mainProject);
		List<WfTaskRouting> routinglist = getWfTaskPreviuosRouting(10, projectTask.getWfPlanTask());
		if(routinglist == null || routinglist.size() == 0)
		{
			System.out.println("No any Prievious Routing For The Task " + projectTask.getRecid());

			return false;
		}
		for(WfTaskRouting routeTask : routinglist)
		{
			for(WfProjectTask task : allProjectTasks)
			{
				/**
				 * if previuos branch has been executed
				 * */
				// if(routeTask.getWfPlanTask1().getRecid() == task.getWfPlanTask().getRecid())
				if(routeTask.getWfPlanTask1().getRecid().equals(task.getWfPlanTask().getRecid()))
				{
					if(task.getIsProcessed() == null || !task.getIsProcessed())
					{
						System.out.println("Task previuos not executed yet " + task.getRecid());
						return false;
					}
					else
					{
						return true;
					}
				}
			}
		}
		return false;
	}

	@SuppressWarnings("deprecation")
	private List<WfTaskRouting> getWfTaskPreviuosRouting(int maxresults, WfPlanTask wfPlanTask)
	{

		// Session Session = SessionUtil.getCurrentSession();
		Session session = SessionUtil.getSession();
		List<WfTaskRouting> retList = WorkFlowEngineQueryUtil.getPreviuosRoutingTasks(session, wfPlanTask);
		// retList = CloneUtil.cloneWfTaskRoutingList(retList);
		EngineUtil.closeSession(session);
		return retList;

	}

	public WfTaskType getwfTaskTypeByTypeID(long tasktype)
	{
		// Session session = SessionUtil.getCurrentSession();
		Session session = SessionUtil.getSession();
		WfTaskType taskType = WorkFlowEngineQueryUtil.getWfTaskType(session, tasktype);
		EngineUtil.closeSession(session);
		return taskType;
	}

	private WfProjectTaskStatus getWfProjectTaskStatusByID(long i)
	{
		// Session session = SessionUtil.getCurrentSession();
		Session session = SessionUtil.getSession();
		WfProjectTaskStatus wfProjectTaskStatus = WorkFlowEngineQueryUtil.getWfProjectTaskStatusByID(i, session);
		EngineUtil.closeSession(session);
		return wfProjectTaskStatus;
	}

	public List<WfProjectTask> loadAssignedJoinTasks(int maxresults)
	{
		// ------------------------ get process tasks
		WfTaskType taskType = getwfTaskTypeByTypeID(7l); // join
		WfProjectTaskStatus taskStatus = getWfProjectTaskStatusByID(4l); // assigned
		WfProjectStatus projectStatus = getWfProjectStatusByID(2); // inprocess
		//
		// Session session = SessionUtil.getCurrentSession();
		Session session = SessionUtil.getSession();
		List<WfProjectTask> tasklist = WorkFlowEngineQueryUtil.getProjectTasks(session, projectStatus, maxresults, taskType, taskStatus, false);
		// clone

		EngineUtil.closeSession(session);
		//
		return tasklist;
	}

	private WfProjectStatus getWfProjectStatusByID(long i)
	{
		// Session session = SessionUtil.getCurrentSession();
		Session session = SessionUtil.getSession();
		WfProjectStatus projectStatus = WorkFlowEngineQueryUtil.getwfProjectStatusByID(i, session);
		EngineUtil.closeSession(session);
		return projectStatus;
	}

	/**
	 * <br>
	 * Update Join task as sucessd to can execute next one
	 * 
	 * */

	private void updateTask(WfProjectTask task)
	{
		WfProjectTaskStatus taskStatus = getWfProjectTaskStatusByID(1l); // success
		task.setWfProjectTaskStatus(taskStatus);
		task.setStartTime(new Date());
		task.setUserId(0l);
		task.setGroupId(0l);
		task.setIsProcessed(true);
		task.setEndTime(new Date());

		// session.merge(task);
		// session.beginTransaction().commit();
		//
		// Session session = SessionUtil.getCurrentSession();
		Session session = SessionUtil.getSession();
		session.clear();
		WorkFlowEngineQueryUtil.updateWfProjectTask(task, session);
		EngineUtil.closeSession(session);

	}

	// private WfProjectTask getWfProjectTaskById(Long recid)
	// {
	// Session session = SessionUtil.getCurrentSession();
	// return WorkFlowEngineQueryUtil.getWfProjectTask(session, recid,
	// 10).get(0);
	// }

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		(new Thread(new JoinManger())).start();

	}

}
